// Created by: Keith Wyss
// Updated by: Evan McCullough 4/14/2011

import javax.swing.*;
import java.awt.*;
import java.util.*;
import javax.swing.plaf.basic.*;
import javax.swing.border.*;
import javax.swing.table.*;
import javax.swing.event.*;
import javax.imageio.*;
import javax.*;
import java.io.*;
import java.awt.event.*;
import java.sql.*;
import java.util.*;

public class UserUpdateForm implements ActionListener{
    JPanel updatePanel;
  JButton submitUser, selectCar, deleteCar, back, newCar, editCH, rmVehicle, rmRecord;
  JTextField newUserName, newEmail;
    JPasswordField newpassfield, oldpassfield;
  JLabel newname, oldpass, newpass, newE;
    JPanel textPanel, buttonPanel, oldcontent;
  JComboBox carSelector, chVehicles, chRecords;
    Connection dbConnection = null;
    User currUser;
    Car currCar;
    AutoBiographyGUI parent;
    Statement stmnt = null;
    ResultSet r = null;
    ArrayList<Car> cars;
    JFrame frame;
    
	public UserUpdateForm(JFrame window, Connection dConnection, User curuser, Car curcar, AutoBiographyGUI parentArg){
        frame = window;
        cars = new ArrayList<Car>();
        parent = parentArg;
        currCar = curcar;
        currUser = curuser;
        
        dbConnection = dConnection;
        try{
          stmnt = dbConnection.createStatement();  

        }
        catch(SQLException statcreat){
            System.out.println("Error creating statement: " + statcreat);
        }
        oldcontent = (JPanel) frame.getContentPane();
        
        
        updatePanel = new JPanel(new BorderLayout());
        carSelector = new JComboBox();
        updateCombo();
        
        
        // retrieve car database
        
        try{
            r = stmnt.executeQuery("SELECT * FROM CARS WHERE USER = '" + currUser.username + "'");
            //choice 7
            while(r.next()){
                cars.add(new Car(r.getString("MAKE"), r.getString("MODEL"), r.getString("VIN"), r.getString("USER"), r.getString("YEAR")));
            }
        }catch(SQLException e1){
            System.out.println("Error creating cars array.");
            System.out.println(e1);
        }
        
// Create GUI for adding a new car *********
        
        //Create GUI for buttons
        submitUser = new JButton("Submit User Info");
        submitUser.addActionListener(this);

        selectCar = new JButton("Select Vehicle");
        selectCar.addActionListener(this);

        newCar = new JButton("New Car");
        newCar.addActionListener(this);

        back = new JButton("Go back.");
        back.addActionListener(this);

        deleteCar = new JButton("Delete Vehicle");
        deleteCar.addActionListener(this);

        editCH = new JButton("Edit Clearinghouse DB");
        editCH.addActionListener(this);

        buttonPanel = new JPanel(new FlowLayout());
        buttonPanel.add(submitUser);
        buttonPanel.add(selectCar);
        buttonPanel.add(newCar);
        buttonPanel.add(deleteCar);
        if(!currUser.chID.equals("NULL"))
          buttonPanel.add(editCH);
        buttonPanel.add(back);
        
        textPanel = new JPanel(new GridLayout(6, 1));
        newname = new JLabel("Enter your new username. All non alpha-numerics will be stripped.");
        newUserName = new JTextField(currUser.username);
        newE = new JLabel("Enter your new e-mail address.");
        newEmail = new JTextField("");
        oldpass = new JLabel("Enter your old password.");
        newpass = new JLabel("Enter you new password. All non alpha-numerics will be stripped.");
        oldpassfield = new JPasswordField("");
        newpassfield = new JPasswordField("");
        
        textPanel.add(newname);
        textPanel.add(newUserName);
        textPanel.add(newE);
        textPanel.add(newEmail);
        textPanel.add(oldpass);
        textPanel.add(oldpassfield);
        textPanel.add(newpass);
        textPanel.add(newpassfield);
        
        
        updatePanel.add(buttonPanel, BorderLayout.SOUTH);
        updatePanel.add(carSelector, BorderLayout.NORTH);
        updatePanel.add(textPanel, BorderLayout.CENTER);
        updatePanel.setVisible(true);
        buttonPanel.setVisible(true);
        textPanel.setVisible(true);
        frame.setSize(1000, 500);
        frame.setContentPane(updatePanel);
    }
    
    public void updateCombo(){
        try{
            carSelector.removeAllItems();
            System.out.println("Username: " + currUser.username);
            r = stmnt.executeQuery("SELECT * FROM CARS WHERE USER = '"+ currUser.username + "'");
            //choice 7
            while(r.next()){
                carSelector.addItem(r.getString("YEAR")+" "+r.getString("MAKE")+" "+r.getString("MODEL"));
            }
        }catch(SQLException e0){
            System.out.println("Error loading car names for user.");
            System.out.println(e0);
        }    
    }
    public void actionPerformed(ActionEvent e1){
        if(e1.getSource() == selectCar){
                String makeModelYear;
                for(int i=0; i<cars.size(); i++){
                    makeModelYear = cars.get(i).year+" "+cars.get(i).make+" "+cars.get(i).model;
                    if(makeModelYear.equals(carSelector.getSelectedItem().toString()) && currUser.username.equals(cars.get(i).user)){
                        currCar = cars.get(i);
                        JOptionPane.showMessageDialog(null, "You have selected your " + makeModelYear + ".");
                    }
                }
        }
        else if (e1.getSource() == submitUser){
            String UID = currUser.username;
            String pass = sanitize(new String(oldpassfield.getPassword()));
            SecureLogin safe = new SecureLogin();
            String newId = sanitize(newUserName.getText());
            String newpass = sanitize(new String(newpassfield.getPassword()));
            String newerEmail = sanitize(new String(newEmail.getText()));
            boolean valid = true;
            if (newId.equals("") && valid){
                JOptionPane.showMessageDialog(null, "You did not enter a username.");
                valid = false;
            }
            if (newpass.equals("") && valid){
                JOptionPane.showMessageDialog(null, "You did not enter a new password.");
                valid = false;
            }
            if(newerEmail.equals("") && valid){
              JOptionPane.showMessageDialog(null, "You did not enter a new email.");
              valid = false;
            }
            ResultSet rstest = null;
            if(valid){
              try{
                PreparedStatement pstmttest = dbConnection.prepareStatement("SELECT * FROM USERS WHERE UID = ?");
                  //choice 4
                pstmttest.setString(1, newId);
                rstest = pstmttest.executeQuery();
              }
              catch(Exception d){
                JOptionPane.showMessageDialog(null, "Can't test if the username is unique:\n\n" + d.toString());
                valid = false;
              }
              try{
                boolean found = true;
                if (valid){
                    found = rstest.next();
                }
                  if (newId.equals(UID)){
                      found = false;
                  }
                if(valid && found){
                    JOptionPane.showMessageDialog(null, "That Username is not unique.");
                    valid = false;
                }
              }
              catch(Exception i){
                JOptionPane.showMessageDialog(null, "Can't test if the user name is unique:\n\n" + i.toString());
                valid = false;
              }
            }
            if (valid){
                try{
                if (safe.authenticate(dbConnection, UID, pass)){
                        try{ 
                              String hash = new SecureLogin().getHashString(dbConnection, UID, newpass);
                              PreparedStatement state = dbConnection.prepareStatement("UPDATE USERS SET UID = ?,PASSWORD = ?,EMAIL= ? WHERE UID = ?");
                            //choice = 11
                                state.setString(1, newId);
                                state.setString(2, hash);
                                state.setString(3, newerEmail);
                                state.setString(4, UID);
                                state.executeUpdate();
                            
                                //Retrieve User so that it can be added to arraylist in Autobiography.***
                                //*****Remove current user
                                AutoBiography.removeUser(currUser);
                            try{ 
                                System.out.println("-"+UID+"-\n-"+newId+"-");
                                PreparedStatement statecar = dbConnection.prepareStatement("UPDATE CARS SET USER = ? WHERE USER = ?");
                                //Choice 12
                                statecar.setString(1, newId);
                                statecar.setString(2, UID);
                                statecar.executeUpdate();
                            }
                            catch(SQLException carexcept){
                                JOptionPane.showMessageDialog(null, "Error updating cars \n\n" + carexcept);
                            }
                            
                                currUser = returnUser(newId, dbConnection);
                                AutoBiography.addUser(currUser);
                                AutoBiography.setUser(currUser);
                                parent.setUser(currUser);
                                JOptionPane.showMessageDialog(null, "You have successfully changed your info " + newId);
                                frame.setSize(1000, 800);
                                frame.setContentPane(oldcontent);
                                
                        }
                        catch(SQLException q){
                            JOptionPane.showMessageDialog(null, "Could not update user info:\n\n" + q.toString());
                        }

                }
                else{
                    JOptionPane.showMessageDialog(null, "Incorrect password. Try again. Nothing has been changed.");
                }
                }
                catch(Exception auth){
                    JOptionPane.showMessageDialog(null, "Can't access authentication service to update info.\n\n " + auth);
                }
            }
        }
        else if(e1.getSource() == editCH){
          updatePanel.removeAll();
          JPanel vehiclePanel = new JPanel();
          JPanel recordPanel = new JPanel();

          chVehicles = new JComboBox();
          chRecords = new JComboBox();
          try{
            r = stmnt.executeQuery("SELECT * FROM CARS WHERE CH_ID = '"+currUser.chID +"'");
              //choice = 13
            while(r.next()){
              if(r.getString("USER").equals(currUser.username)){
                chVehicles.addItem(r.getString("YEAR")+" "+ r.getString("MAKE")+" "+ r.getString("MODEL")+" "+ r.getString("VIN"));
              }
            }

            r = stmnt.executeQuery("SELECT * FROM CLEARINGHOUSE WHERE VIN = '"+currCar.vin+"'");
              //choice 14
            while(r.next()){
              chRecords.addItem(r.getString("DATE_TIME"));
            } 
          }catch(SQLException rmE){
            System.out.println("Clearinghouse removal query error: "+rmE);
          } 

          rmVehicle = new JButton("Remove Vehicle");
          rmVehicle.addActionListener(this);
          
          rmRecord = new JButton("Remove Record");
          rmRecord.addActionListener(this);

          updatePanel.setLayout(new GridLayout(2, 2));
          updatePanel.add(chVehicles);
          updatePanel.add(rmVehicle);
          updatePanel.add(chRecords);
          updatePanel.add(rmRecord);
          updatePanel.validate();
        }
        else if(e1.getSource() == back){
            frame.setSize(1200, 800);
            frame.setContentPane(oldcontent);

        }
        else if (e1.getSource() == rmVehicle){
          String carTitle = (String)chVehicles.getSelectedItem();
          String slot = carTitle;
          
          StringTokenizer slots;
          
          slots = new StringTokenizer(slot, " ");

          String yr = slots.nextToken();
          String ma = slots.nextToken();
          String mo = slots.nextToken();
          String vin = slots.nextToken();
          try{
            stmnt.executeUpdate("DELETE FROM CLEARINGHOUSE WHERE VIN = '"+vin+"'");
              //choice = 15
          }catch(SQLException rmVe){
            System.out.println("Vehicle CH Removal error: "+rmVe);
          }
            frame.setSize(1200, 800);
            frame.setContentPane(oldcontent);
        }
        else if(e1.getSource() == rmRecord){
          String recTitle = (String)chRecords.getSelectedItem();
          String slot = recTitle;

          try{
            stmnt.executeUpdate("DELETE FROM CLEARINGHOUSE WHERE VIN = '"+currCar.vin+"' AND DATE_TIME = '"+slot+"'");
              //choice = 16
          }catch(SQLException rmVe){
            System.out.println("Vehicle CH Removal error: "+rmVe);
          }
          frame.setSize(1200, 800);
          frame.setContentPane(oldcontent);
        } 
         
        else if(e1.getSource() == newCar){
            updatePanel.setVisible(false);
            frame.setVisible(false);
            new CarSelector(currUser, dbConnection);
        }
        else if(e1.getSource() == deleteCar){
            String makeModelYear;
            for(int i=0; i<cars.size(); i++){
                makeModelYear = cars.get(i).year+" "+cars.get(i).make+" "+cars.get(i).model;
                if(makeModelYear.equals(carSelector.getSelectedItem().toString()) && currUser.username.equals(cars.get(i).user)){
                    currCar = cars.get(i);
                    int choice = JOptionPane.showConfirmDialog(null, "Delete your " + makeModelYear + " with \n" + cars.get(i).vin + "?" ,"Really Delete", JOptionPane.YES_NO_OPTION);
                    if (choice == 0){
                        try{
                            PreparedStatement deleteacar = dbConnection.prepareStatement("DELETE FROM CARS WHERE VIN = ?");
                            //Choice 17
                            String input = LoginScreen.sanitize(cars.get(i).vin);
                            System.out.println(input);
                            deleteacar.setString(1, input);
                            deleteacar.executeUpdate();
                            boolean needacar = false;
                            if (cars.remove(i).equals(currCar)){
                                needacar = true;
                            }
                            JOptionPane.showMessageDialog(null, "Delete operation Successful.");
                            if (cars.size() == 0){
                                JOptionPane.showMessageDialog(null, "You must register a new car to proceed.");
                                updatePanel.setVisible(false);
                                frame.setVisible(false);
                                new CarSelector(currUser, dbConnection);                   
                            }
                            else if (needacar){
                                makeModelYear = cars.get(0).year+" "+cars.get(0).make+" "+cars.get(0).model;

                                JOptionPane.showMessageDialog(null, "You deleted your selected car.\n Your selected car is now a " + makeModelYear );
                                updateCombo();
                                stmnt.executeUpdate("UPDATE USERS SET NUMVEHICLES = NUMVEHICLES-1 WHERE UID = '" + currUser.username + "'");
                                //choice 18
                            }
                            
                        }
                        catch(SQLException delExcept){
                            JOptionPane.showMessageDialog(null, "Delete operation failed. Reason: \n\n" + delExcept);
                        }
                    }
                }
            }        
        }
    }
        public String sanitize(String in){
            String result;
            result = in.replaceAll("[^A-Za-z0-9 ]", "");
            return result;
        }
        
        private User returnUser(ResultSet rset){
            User currUser = null;
            try{
                rset.next();
                currUser = new User(rset.getString("FIRSTNAME"), rset.getString("LASTNAME"), rset.getString("UID"), rset.getString("PASSWORD"), rset.getString("USERTYPE"), rset.getString("EMAIL"), rset.getInt("NUMVEHICLES"), rset.getString("CH_ID"));
            }
            catch(SQLException sqlf){
                JOptionPane.showMessageDialog(null, "Getting the user from database failed. Returning null user");
                System.out.println(sqlf);
                currUser = new User("NULL", "NULL","NULL","NULL","NULL", "NULL", -1, "NULL");
            }
            finally{
                return currUser;
            }
        }
        private User returnUser(String UID, Connection connect){
            User currUser = null;

            try{
                  PreparedStatement pstt = connect.prepareStatement("SELECT * FROM USERS WHERE UID = ?");
                  pstt.setString(1, UID);

                  ResultSet rset = pstt.executeQuery();
                  rset.next();
                  currUser = new User(rset.getString("FIRSTNAME"), rset.getString("LASTNAME"), rset.getString("UID"), rset.getString("PASSWORD"), rset.getString("USERTYPE"), rset.getString("EMAIL"), rset.getInt("NUMVEHICLES"), rset.getString("CH_ID"));
            }
            catch(SQLException sqlf){
                JOptionPane.showMessageDialog(null, "Getting the user from database failed. Returning null user");
                System.out.println(sqlf);
                currUser = new User("NULL", "NULL","NULL","NULL","NULL", "NULL", -1, "NULL");
            }
            finally{
                return currUser;
            }
        }
    

    
}
